package lee.vioson.ebook.viewmodels

import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
import lee.vioson.composecommon.base.mvi.BaseViewModel
import lee.vioson.composecommon.base.mvi.Reducer
import lee.vioson.composecommon.base.mvi.UiEvent
import lee.vioson.composecommon.base.mvi.UiState
import lee.vioson.ebook.data.AppContainer
import lee.vioson.remotedata.bean.Book
import lee.vioson.remotedata.bean.HomeData

/**
 *Author:viosonlee
 *Date:2023/6/3
 *DESCRIPTION:
 */
class HomeViewModel(private val appContainer: AppContainer) :
    AppViewModel<HomeViewModel.State, HomeViewModel.Event>(appContainer.appEvent) {

    private val reducer = SubReducer(State())

    val bannerData = appContainer.homeRepository.bannerData
        .catch { handleException(it) }
        .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), listOf())

//    val cacheHomeData = appContainer.homeRepository.fetchCacheHomeData()
//        .catch { handleException(it) }
//        .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), null)

    fun homeData(isShowLoading: Boolean) =
        appContainer.homeRepository.fetchHomeData(appContainer.uniqueId)
            .catch { handleException(it) }
            .onEach { sendEvent(Event.OnDataChange(it)) }
            .onStart { if (isShowLoading) showLoading() }
            .onCompletion { if (isShowLoading) dismissLoading() }
            .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), null)
            .launchIn(viewModelScope)

    override val state: StateFlow<State>
        get() = reducer.state

    override fun sendEvent(event: Event) {
        reducer.sendEvent(event)
    }

    val articles = mutableListOf<Book>()

    private class SubReducer(initialState: State) :
        Reducer<State, Event>(initialState) {
        override fun reduce(oldState: State, event: Event) {
            when (event) {
                is Event.OnDataChange -> setState(oldState.copy(homeData = event.homeData))
            }
        }
    }


    sealed class Event : UiEvent {
        data class OnDataChange(val homeData: HomeData?) : Event()
    }

    data class State(val isVip: Boolean = false, val homeData: HomeData? = null) : UiState
}

